#include "myhighlight.h"

#include <QTextStream>
#include<QDebug>
MyHighlight::MyHighlight(QTextDocument *parent):QSyntaxHighlighter(parent)
{
    addNormalTextFormat();
    addNumberTextFormat();
    addStringTextFormat();
    addCommentTextFormat();
    addKeyWordsFormat();
    addClassNameFormat();
    addFunctionFormat();
}

void MyHighlight::highlightBlock(const QString &text)
{
    foreach(const HighlightRule &rule,highlightRules){
        QRegExp regExp(rule.pattern);
        int index = regExp.indexIn(text);
        while(index>=0)
        {
            int length = regExp.matchedLength();
            setFormat(index,length,rule.format);
            index = regExp.indexIn(text,index+length);
        }
    }
    //对于多行注释
    addmulLineTextFormat(text);
}

void MyHighlight::addNormalTextFormat()
{
    HighlightRule rule;
    QTextCharFormat normalTextFormat;
    normalTextFormat.setForeground(QColor(0,0,0));
    normalTextFormat.setFont(QFont(mFontFamily,mFontSize));

    rule.pattern = QRegExp("[a-zA-Z0-9]+");
    rule.format = normalTextFormat;

    highlightRules.append(rule);
}

void MyHighlight::addNumberTextFormat()
{
    HighlightRule rule;
    QTextCharFormat numberTextFormat;
    numberTextFormat.setForeground(QColor(250,80,50));
    numberTextFormat.setFont(QFont(mFontFamily,mFontSize));

    rule.pattern = QRegExp("\\b\\d+|\\d+\\.\\d+\\b");
    rule.format = numberTextFormat;

    highlightRules.append(rule);
}

void MyHighlight::addStringTextFormat()
{
    HighlightRule rule;
    QTextCharFormat numberTextFormat;
    numberTextFormat.setForeground(QColor(0,180,180));
    numberTextFormat.setFont(QFont(mFontFamily,mFontSize));

    rule.format = numberTextFormat;

    rule.pattern = QRegExp("'[^']*'");
    highlightRules.append(rule);

    rule.pattern = QRegExp("\\/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*\\/");
    highlightRules.append(rule);

}

void MyHighlight::addCommentTextFormat()
{
    HighlightRule rule;
    QTextCharFormat numberTextFormat;
    numberTextFormat.setForeground(Qt::darkGreen);
    numberTextFormat.setFont(QFont(mFontFamily,mFontSize));

    rule.format = numberTextFormat;

    rule.pattern = QRegExp("\\/\\/.*$");
    highlightRules.append(rule);

    rule.pattern = QRegExp("\"[^\"]*\"");
    highlightRules.append(rule);
}

void MyHighlight::addmulLineTextFormat(const QString &text)
{
    setCurrentBlockState(0);

    // /*
    QRegExp commentStartRegExp("/\\*");
    // */
    QRegExp commentEndRegExp("\\*/");

    //高亮格式
    QTextCharFormat multiLineCommentFormat;
    multiLineCommentFormat.setFont(QFont(mFontFamily,mFontSize));
    multiLineCommentFormat.setForeground(Qt::darkGreen);
    multiLineCommentFormat.setFontItalic(true);

    int startIndex = 0;
    if(previousBlockState()!=1)
        startIndex= commentStartRegExp.indexIn(text);

    while(startIndex>=0){
        int endIndex = commentEndRegExp.indexIn(text,startIndex);
        int commentLength = 0;
        if(endIndex==-1){//没有结束位置
            setCurrentBlockState(1);
            commentLength = text.length()-startIndex;
        }else{//有结束位置
            commentLength = endIndex-startIndex+commentEndRegExp.matchedLength();
        }
        //设置格式
        setFormat(startIndex,
                  commentLength,
                  multiLineCommentFormat);
        startIndex = commentStartRegExp.indexIn(text,commentLength+startIndex);
    }
}

void MyHighlight::addKeyWordsFormat()
{
    QFile file(":/config/KeyWords.txt");
    QTextStream keyWordStream(&file);

    HighlightRule rule;
    QTextCharFormat keywordFormat;
    keywordFormat.setFont(QFont(mFontFamily,mFontSize));
    keywordFormat.setForeground(Qt::darkMagenta);
    rule.format = keywordFormat;

    if(file.open(QIODevice::ReadOnly|QIODevice::Text))
    {
        keyWordStream.seek(0);
        QString line;
        while(!keyWordStream.atEnd())
        {
            line = keyWordStream.readLine();
            if(line != "")
            {
                rule.pattern = QRegExp("\\b"+line+"\\b");
                highlightRules.append(rule);
            }
        }
        file.close();
    }
    else
    {
        qDebug()<<"error"<<file.errorString();
    }


}

void MyHighlight::addClassNameFormat()
{
    HighlightRule rule;
    QTextCharFormat ClassNameFormat;
    ClassNameFormat.setForeground(QColor(150,20,100));
    ClassNameFormat.setFont(QFont(mFontFamily,mFontSize));
    ClassNameFormat.setFontWeight(99);

    rule.format = ClassNameFormat;

    rule.pattern = QRegExp("\\b[A-Z]+\\w*");
    highlightRules.append(rule);
}

void MyHighlight::addFunctionFormat()
{
    HighlightRule rule;
    QTextCharFormat FunctionFormat;
    FunctionFormat.setForeground(QColor(200,0,100));
    FunctionFormat.setFont(QFont(mFontFamily,mFontSize));
    FunctionFormat.setFontWeight(99);

    rule.format = FunctionFormat;

    rule.pattern = QRegExp("\\w+\\(");
    highlightRules.append(rule);
    rule.pattern = QRegExp("\\)");
    highlightRules.append(rule);
}
